package io.bdmc.common.http;

import java.util.HashMap;
import java.util.Map;

import com.iotplatform.client.NorthApiClient;
import com.iotplatform.client.NorthApiException;
import com.iotplatform.client.dto.ClientInfo;
import com.iotplatform.client.dto.CommandDTO2;
import com.iotplatform.client.dto.CommandNA2CloudHeader;
import com.iotplatform.client.dto.InvokeDeviceServiceOutDTO;
import com.iotplatform.client.dto.QueryBatchSubInDTO;
import com.iotplatform.client.dto.QueryBatchSubOutDTO;
import com.iotplatform.client.dto.SubDeviceDataInDTO;
import com.iotplatform.client.dto.SubscriptionDTO;
import com.iotplatform.client.invokeapi.DeviceServiceInvocation;
import com.iotplatform.client.invokeapi.SubscriptionManagement;

public class AuthUtil {

	private static NorthApiClient northApiClient = null;
	private static String appId = "RI1wIdGD6IRrACHXo5aqJmBScaEa";
	private static String secret = "S_NDBECyBbiIsnZAyTYufcHtGpUa";
	private static String platformIp = "180.101.147.89";
	private static String platformPort = "8743";

	public static NorthApiClient initApiClient() {
		if (northApiClient != null) {
			return northApiClient;
		}
		northApiClient = new NorthApiClient();

		// PropertyUtil.init("./src/main/resources/application.properties");

		ClientInfo clientInfo = new ClientInfo();
		clientInfo.setPlatformIp(platformIp);
		clientInfo.setPlatformPort(platformPort);
		clientInfo.setAppId(appId);
		// clientInfo.setSecret(PropertyUtil.getProperty("secret"));
		clientInfo.setSecret(secret);

		try {
			northApiClient.setClientInfo(clientInfo);
			northApiClient.initSSLConfig();
		} catch (NorthApiException e) {
			System.out.println(e.toString());
		}

		return northApiClient;
	}

	public static QueryBatchSubOutDTO getAllSubs(String accessToken) throws NorthApiException {
		NorthApiClient northApiClient = AuthUtil.initApiClient();
		SubscriptionManagement subscriptionManagement = new SubscriptionManagement(northApiClient);
		QueryBatchSubInDTO qbsInDTO = new QueryBatchSubInDTO();
		qbsInDTO.setAppId(appId);
		QueryBatchSubOutDTO qbsOutDTO = subscriptionManagement.queryBatchSubscriptions(qbsInDTO, accessToken);
		return qbsOutDTO;
	}

	public static SubscriptionDTO SubscribeDeviceBussiness(String apiName, String accessToken) {
		System.out.println("======subscribe to device business data notification======");
		NorthApiClient northApiClient = AuthUtil.initApiClient();
		SubscriptionManagement subscriptionManagement = new SubscriptionManagement(northApiClient);
		String callbackUrl = "http://39.106.215.87:8888/msg/ct";
		SubscriptionDTO subDTO = subDeviceData(subscriptionManagement, apiName, callbackUrl, accessToken);
		//subDeviceData(subscriptionManagement, "deviceDataChanged", callbackUrl, accessToken);
		return subDTO;
	}

	private static SubscriptionDTO subDeviceData(SubscriptionManagement subscriptionManagement, String notifyType,
			String callbackUrl, String accessToken) {
		SubDeviceDataInDTO sddInDTO = new SubDeviceDataInDTO();
		sddInDTO.setNotifyType(notifyType);
		sddInDTO.setCallbackUrl(callbackUrl);
		try {
			SubscriptionDTO subDTO = subscriptionManagement.subDeviceData(sddInDTO, null, accessToken);
			System.out.println(subDTO.toString());
			return subDTO;
		} catch (NorthApiException e) {
			System.out.println(e.toString());
		}
		return null;
	}

	public static InvokeDeviceServiceOutDTO sendXY(String deviceId,String accessToken){
		NorthApiClient northApiClient = AuthUtil.initApiClient();
    	DeviceServiceInvocation deviceServiceInvocation = new DeviceServiceInvocation(northApiClient);
		InvokeDeviceServiceOutDTO idsOutDTO = modifyBrightness(deviceServiceInvocation, deviceId, accessToken);
        return idsOutDTO;
	}

	public static SubscriptionDTO querySingleSub(String subId,String accessToken) throws NorthApiException {
		NorthApiClient northApiClient = AuthUtil.initApiClient();
		SubscriptionManagement subscriptionManagement = new SubscriptionManagement(northApiClient);
		SubscriptionDTO subDTO2 = subscriptionManagement.querySingleSubscription(subId, null, accessToken);
			//System.out.println(subDTO2.toString());
			return subDTO2;
	}

    private static InvokeDeviceServiceOutDTO modifyBrightness(DeviceServiceInvocation deviceServiceInvocation, String deviceId,String accessToken) {
    	CommandDTO2 cmdDTO = new CommandDTO2();
        CommandNA2CloudHeader cmdHeader = new CommandNA2CloudHeader();
        cmdHeader.setMode("NOACK");//set mode to NOACK or ACK according to the business quest
        cmdHeader.setMethod("PUT");//"PUT" is the command name defined in the profile
        cmdDTO.setHeader(cmdHeader);
        
        Map<String, Object> body = new HashMap<String, Object>();
        body.put("val", "XY");//"brightness" is the command parameter name defined in the profile
        cmdDTO.setBody(body);
        
        //"Brightness" is the serviceId defined in the profile
        InvokeDeviceServiceOutDTO idsOutDTO;
		try {
			/**---------------------invoke device service------------------------*/
			String serviceId = "Msg";//"Brightness" is the serviceId defined in the profile
			idsOutDTO = deviceServiceInvocation.invokeDeviceService(deviceId, serviceId, cmdDTO, null, accessToken);
			return idsOutDTO;
		} catch (NorthApiException e) {
			if ("100428".equals(e.getError_code())) {
				System.out.println("please make sure the device is online");
			}
			System.out.println(e.toString());
		}
        return null;
    }
	// public static String getAesPropertyValue(String propertyName) {
	// String aesPwd = "123987"; //this is a test AES password

	// // String originalProperty = "gPnTWO52yrobtjyobykkf12P8f4a";
	// // byte[] temp = AesUtil.encrypt(originalProperty, aesPwd);
	// // String hexStrResult = HexParser.parseByte2HexStr(temp);
	// // System.out.println("encrypted secret hex sting is ï¼š" + hexStrResult);

	// PropertyUtil.init("./src/main/resources/application.properties");
	// byte[] secret =
	// HexParser.parseHexStr2Byte(PropertyUtil.getProperty(propertyName));
	// return new String(AesUtil.decrypt(secret, aesPwd));
	// }

	// public static String getAesSecretValue() {
	// String aesPwd = "123987"; //this is a test AES password
	// byte[] bssecret = HexParser.parseHexStr2Byte(secret);
	// return new String(AesUtil.decrypt(bssecret, aesPwd));
	// }
}
